import os, time, abc
import os, zipfile, shutil
from pathlib2 import Path
import json, os

def copy_file(source_path, target_path, file_name):
    source_file_path = os.path.join(source_path, file_name)
    target_file_path = os.path.join(target_path, file_name)
    if os.path.exists(target_file_path):
        print("文件:{}已在目录{}下存在".format(file_name, target_path))
        return None
    else:
        if os.path.exists(source_file_path):
            shutil.copyfile(source_file_path, target_file_path)
            print("拷贝文件:{}到{}成功".format(file_name, target_path))
            return True
        else:
            print("源文件目录:{}下文件{}不存在".format(source_path, file_name))
            return False

def unzip(file_path):
    cmd = "cd {} & 7z x -tzip -y \"{}\"".format(os.getcwd(), file_path)
    return os.system(cmd)


class File(metaclass=abc.ABCMeta):
    def __init__(self, file_path):
        self.isValid = True
        self.file_path = os.path.abspath(file_path)
        self.file_type = file_path.split(".")[-1]
        _, self.file_name = os.path.split(file_path)
        # print(os.path.isfile(self.file_path), self.file_path)
        # print(self.check_filetype())
        if os.path.isfile(self.file_path) and self.check_filetype():
            self.isValid = True
        else:
            print("{}\n文件不存在或者格式有误".format(self.file_path))
            self.isValid = False
    
    @abc.abstractmethod
    def check_filetype(self):
        pass

    def getModifiedTime(self):
        modifiedtime = time.ctime(os.path.getmtime(self.file_path)).split(" ")
        for i in modifiedtime:
            if ":" in i:
                modifiedtime = i
        modifiedtime = modifiedtime.split(":")
        modifiedtime = list(map(float, modifiedtime))
        return modifiedtime


class Json(File):
    def __init__(self, file_path, code="utf-8"):
        super().__init__(file_path)
        # 自动读取
        self.code = code
        self.read_json()


    def check_filetype(self):
        if self.file_type == "json" or self.file_type == "config":
            return True
        else:
            return False

    def read_json(self):
        if not self.isValid:
            return
        contents = Path(self.file_path).read_text(encoding=self.code)
        self.data = json.loads(contents)
        return self.data

    def save_json(self, target_path=""):
        if target_path == "":
            target_path = self.file_path
        with open(target_path, 'w', encoding=self.code) as f:
            f.write(json.dumps(self.data, ensure_ascii=False,indent=1))

class Txt(File):
    def __init__(self, file_path):
        super().__init__(file_path)

    def check_filetype(self):
        if self.file_type != "txt":
            return False
        else:
            return True

    def read_line(self):
        # 生成器
        count = 0
        position = 0
        try:
            with open(self.file_path, mode='r', encoding='utf8') as f1:
        
                while True:
                    line = f1.readline().strip()
                    if line:
                        count += 1
                        if __name__ == "__main__":
                            print("count %s line %s" % (count, line))
                    time.sleep(0.05)
                    yield line
                    cur_position = f1.tell() # 记录上次读取文件的位置
        
                    if cur_position == position:
                        continue
                    else:
                        position = cur_position
        except:
            with open(self.file_path, mode='r', encoding='gb18030') as f1:
                while True:
                    line = f1.readline().strip()
                    if line:
                        count += 1
                        if __name__ == "__main__":
                            print("count %s line %s" % (count, line))
                    time.sleep(0.1)
                    yield line
                    cur_position = f1.tell() # 记录上次读取文件的位置
        
                    if cur_position == position:
                        continue
                    else:
                        position = cur_position
            

class Zip(File):
    def __init__(self, file_path):
        super().__init__(file_path)

    def check_filetype(self):
        if self.file_type != "zip":
            return False
        else:
            return True

    def unzip(self, destDir=""):
        if not self.isValid:
            return
        else:
            srcDir = self.file_path
            if not os.path.isdir(destDir) and os.path.isdir(srcDir):
                destDir = srcDir
            if os.path.isdir(srcDir) and os.path.isdir(destDir):
                for file_name in os.listdir(srcDir):
                    path = os.path.join(srcDir, file_name)
                    if zipfile.is_zipfile(path):
                        z = zipfile.ZipFile(path, 'r')
                        z.extractall(destDir)
                        z.close()
                        os.remove(path)
                else:
                    print("解压完成，开始转换编码....")
                    for root_path, dir_names, file_names in os.walk(destDir):
                        for fn in file_names:
                            path = os.path.join(root_path, fn)
                            if not zipfile.is_zipfile(path):
                                print("before:", fn)
                                try:
                                    fn = fn.encode('cp437').decode('gbk')
                                    print("after:", fn)
                                    new_path = os.path.join(root_path, fn)
                                    os.rename(path, new_path)
                                except Exception as e:
                                    print('error:', e)
            else:
                raise Exception("src path is not a dir")

class Xml(File):
    def __init__(self, file_path):
        super().__init__(file_path)
    
    def check_filetype(self):
        if self.file_type == "xml" or self.file_type == "xaml":
            return True
        else:
            return False

    def read_xml(self):
        from xml.etree.ElementTree import parse
        DOMTree = parse(self.file_path)
        return DOMTree
    